package com.example.baseutils;

import android.content.Context;
import android.media.AudioManager;
import android.os.Build;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.util.Log;
import android.widget.Toast;

import com.example.baseutils.application.BaseApplication;

import java.util.HashMap;
import java.util.Locale;

public class TtsSpeak {
    private static final String TAG = "TtsSpeak";
    private Context context;
    public TextToSpeech textToSpeech;
    //定义AudioManager，控制播放音量
    private AudioManager mgr;
    private int maxVolume;
    private int currentVolume;
    // 单例模式中获取唯一的TtsSpeek实例
    private static TtsSpeak instance;
    private final HashMap ttsOptions = new HashMap<>();
    private boolean isStopOtherVoice = false;

    private UtteranceProgressListener mUtteranceProgressListener;

    public static TtsSpeak getInstance() {
        if (instance == null) {
            instance = new TtsSpeak(BaseApplication.getInstance());
        }
        return instance;
    }

    public TtsSpeak(Context context) {
        this.context = context;

    }


    public void init() {
        //实例化
        mgr = (AudioManager) context.getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
        //最大音量
        maxVolume = mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        //当前音量
        currentVolume = mgr.getStreamVolume(AudioManager.STREAM_MUSIC);
        Log.i(TAG, "最大音量:  " + maxVolume);
        Log.i(TAG, "当前音量:  " + currentVolume);
        ttsOptions.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "utterance");
        textToSpeech = new TextToSpeech(context.getApplicationContext(), new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                if (status == textToSpeech.SUCCESS) {
                    int result = textToSpeech.setLanguage(Locale.CHINA);//安卓自带的Pico TTS，并不支持中文。所以需要安装 科大讯飞 tts1.0语音包。需要手动完成。
                    Log.i(TAG, "TtsSpeak:result " + result);
//                    setSpeed(1.5f);
//                    setPitch(1.5f);
                    if (result == TextToSpeech.LANG_NOT_SUPPORTED) {
                        Log.e(TAG, "onInit: 不支持当前语言");
                        Toast.makeText(context, "不支持中文语音包", Toast.LENGTH_LONG).show();
                    }
                } else {
                    Log.e(TAG, "onInit: 语音初始化失败");
                    Toast.makeText(context, "语音初始化失败", Toast.LENGTH_LONG).show();
                }
            }

        });

        //使用语音监听，必须设置speak 参数ttsOptions才会生效
        textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() {
            @Override
            public void onStart(String utteranceId) {
                Log.i(TAG, "onStart: ");
                //获取声音焦点，暂停其他声音
                if (isStopOtherVoice)
                    mgr.requestAudioFocus(mAudioFocusChangeListener, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
                if(mUtteranceProgressListener!=null)
                    mUtteranceProgressListener.onStart(utteranceId);
            }

            @Override
            public void onDone(String utteranceId) {
                Log.i(TAG, "onDone: ");
                //释放焦点，还原其他声音
                if (isStopOtherVoice)
                    mgr.abandonAudioFocus(mAudioFocusChangeListener);
                if(mUtteranceProgressListener!=null)
                    mUtteranceProgressListener.onDone(utteranceId);
            }

            @Override
            public void onError(String utteranceId) {
                Log.i(TAG, "onError: ");
            }
        });
    }

    public void setOnUtteranceProgressListener(UtteranceProgressListener listener) {
        mUtteranceProgressListener = listener;
    }

    public void setStopOtherVoice(boolean stopOtherVoice) {
        isStopOtherVoice = stopOtherVoice;
    }

    /**
     * 排队播放
     * 设置语音大小 0-15
     */
    public void SpeechAdd(String text, int volume) {
        this.setVoiceVolume(volume);
        int result;
        result = textToSpeech.speak(text.toString(), TextToSpeech.QUEUE_ADD, ttsOptions);
        // Log.i(TAG, "SpeechAdd: result"+result);
        //  Log.i(TAG, "GetVoiceVolume:   "+mgr.getStreamVolume(AudioManager.STREAM_MUSIC));
    }

    private String tempWords = "";
    private Long lastTime = System.currentTimeMillis();

    public boolean SpeechAdd(String text) {
        int result;
        if (tempWords.equals(text) && (System.currentTimeMillis() - lastTime) < 2000)
            return false;
        lastTime = System.currentTimeMillis();
        tempWords = text;
        result = textToSpeech.speak(text.toString(), TextToSpeech.QUEUE_ADD, ttsOptions);
        Log.i(TAG, "SpeechAdd: result " + result);
        return true;
        //  Log.i(TAG, "GetVoiceVolume:   "+mgr.getStreamVolume(AudioManager.STREAM_MUSIC));
    }

    /**
     * 排队播放系统提示
     */
    public void SystemSpeech(String text) {
        textToSpeech.speak(text.toString(), TextToSpeech.QUEUE_ADD, ttsOptions);
    }

    /**
     * 设置音量
     */
    public void setVoiceVolume(int tempVolume) {
        mgr.setStreamVolume(AudioManager.STREAM_MUSIC, tempVolume, 0);

    }

    /**
     * 设置语速
     * 1.0位正常语速
     * 线性变换
     * 0.5为一般速度，2为两倍速
     */
    public void setSpeed(float speed) {
        textToSpeech.setSpeechRate(speed);
    }

    /**
     * 设置语调
     * 1.0位正常语速
     * 线性变换
     * 0.5为一般速度，2为两倍速
     */
    public void setPitch(float pitch) {
        textToSpeech.setPitch(pitch);
    }

    /**
     * 如果当前有播报，则不播报
     * 用于避免重复播报场景
     * 设置语音大小 0-15
     */
    public void SpeechRepead(String text, int volume) {
        this.setVoiceVolume(volume);
        if (!textToSpeech.isSpeaking()) {
            textToSpeech.speak(text.toString(), TextToSpeech.QUEUE_ADD, ttsOptions);
        }

    }

    /**
     * 如果当前有播报，则不播报
     * 用于避免重复播报场景
     */
    public void SpeechRepead(String text) {
        if (!textToSpeech.isSpeaking()) {
            textToSpeech.speak(text.toString(), TextToSpeech.QUEUE_ADD, ttsOptions);
        }
    }

    /**
     * 判断是否正在播报，如果正在播报，则不进行保存照片的操作
     */
    public boolean isSpeaking() {
        return textToSpeech.isSpeaking();
    }

    /**
     * 打断当前语音，直接播放
     * 设置语音大小 0-15
     */
    public void SpeechFlush(String text, int volume) {
        this.setVoiceVolume(volume);
        int result;
        result = textToSpeech.speak(text.toString(), TextToSpeech.QUEUE_FLUSH, ttsOptions);
        // Log.i(TAG, "SpeechFlush: ");
    }

    /**
     * 打断当前语音，直接播放
     * 设置语音大小 0-15
     */
    public void SpeechFlush(String text) {
        int result = textToSpeech.speak(text.toString(), TextToSpeech.QUEUE_FLUSH, ttsOptions);
        Log.i(TAG, "SpeechFlush: " + result);
    }

    public void stopSpeak() {
        if (textToSpeech.isSpeaking())
            textToSpeech.stop();
    }

    /**
     * 释放资源
     */
    public void ShotDownTts() {
        if (textToSpeech != null) {
            textToSpeech.shutdown();
        }
    }

    private AudioManager.OnAudioFocusChangeListener mAudioFocusChangeListener = focusChange -> {
        if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
            //失去焦点之后的操作
            Log.i(TAG, "失去了焦点");
        } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
            //获得焦点之后的操作
            Log.i(TAG, "获得了焦点 ");
        }
    };

}
